<?xml version='1.0' encoding='utf-8' ?>
<!--  If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/  -->
<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/'>
<channel>
  <title>Tigers, and lions, and bears, oh my!</title>
  <link>http://community.livejournal.com/en_dmitriid/</link>
  <description>Tigers, and lions, and bears, oh my! - LiveJournal.com</description>
  <lastBuildDate>Thu, 24 Apr 2008 13:08:16 GMT</lastBuildDate>
  <generator>LiveJournal / LiveJournal.com</generator>
  <lj:journal>en_dmitriid</lj:journal>
  <lj:journaltype>community</lj:journaltype>
  <image>
    <url>http://p-userpic.livejournal.com/51941952/10276497</url>
    <title>Tigers, and lions, and bears, oh my!</title>
    <link>http://community.livejournal.com/en_dmitriid/</link>
    <width>100</width>
    <height>100</height>
  </image>

<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/6675.html</guid>
  <pubDate>Thu, 24 Apr 2008 13:08:16 GMT</pubDate>
  <title>Musings</title>
  <link>http://community.livejournal.com/en_dmitriid/6675.html</link>
  <description>As I &lt;a href=&quot;http://community.livejournal.com/ru_dmitriid/8537.html&quot;&gt;promised&lt;/a&gt; here are my thoughts:&lt;br /&gt;&lt;br /&gt;1. First of all, pattern matching lets you describe what yo eed with little or no effort. For example, consider these rules:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;{field}
{field, Func}
{field, {&apos;=&apos;, field2}}
&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Frankly, I have a very vague idea how these could be matched using &lt;code&gt;if&lt;/code&gt;s only. I guess you would create a &lt;code&gt;Rule&lt;/code&gt; class and inherit a slew of classes from it. Something like &lt;code&gt;RuleField&lt;/code&gt;, &lt;code&gt;RuleFunc&lt;/code&gt;, &lt;code&gt;RuleOperator&lt;/code&gt; and so on. If you use pattern matching, however, the rules are easily parsed::&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code lang=&quot;erlang&quot;&gt;%%{field}
validate_rule({FieldName}) -&amp;gt;
    ok.

%%{field, Func}
validate_rule({FieldName, Func}) when is_function(Func) -&amp;gt;
    ok.

%%{field, {&apos;=&apos;, field2}}
validate_rule({FieldName, {Operator, FieldName2}}) -&amp;gt;
    ok.
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Such ease, however, may bring (and it does bring me) to my second thought:&lt;br /&gt;&lt;br /&gt;2. WTF-ish code. The thought that you can easily slice through complex constructs makes you write before you think.&lt;br /&gt;&lt;br /&gt;In my case I knew what I wanted to pass to the function, but I had no idea what I expected the function to return. Ok, I&apos;ve parsed the rules, what now?&lt;br /&gt;&lt;br /&gt;As a result, the first version of the function would return a deeply nested list of lists that looked something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code lang=&quot;erlang&quot;&gt;
[[Field, [Error1, Error2]], [Field2, [Error3, Error4]]]
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It took me two additional refactorings to make it return a proper&lt;code&gt;proplist&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;This same &quot;wow, look at how I handle things!&quot; approach resulted in an ugly preprocessing of results before I return these to the user:&lt;br /&gt;&lt;pre&gt;&lt;code lang=&quot;erlang&quot;&gt;
lists:filter(
    fun(Elem) -&amp;gt; 
        case 
            Elem of {} -&amp;gt; false; 
            {_, []} -&amp;gt; false;
            _ -&amp;gt; true 
        end 
    end, 
    lists:flatten(validate1(A, ValidationRules, [])))
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Yup. Get rid of those unwanted elements before the user sees them. Are you scared? I am. I m saddened as well :(&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here&apos;s where my train of thoughts stops...</description>
  <comments>http://community.livejournal.com/en_dmitriid/6675.html</comments>
  <category>erlang</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/6523.html</guid>
  <pubDate>Thu, 24 Apr 2008 07:54:44 GMT</pubDate>
  <title>Validation for erlyweb</title>
  <link>http://community.livejournal.com/en_dmitriid/6523.html</link>
  <description>I&apos;ve written a &lt;a href=&quot;http://groups.google.com/group/erlyweb/browse_frm/thread/1050b3c8024c5030&quot;&gt;validation function for Erlyweb&lt;/a&gt;. First I&apos;ll tell you how it works and then, perhaps, more thoughts on its internals.&lt;br /&gt;&lt;br /&gt;Create a form with four fields:&lt;br /&gt;- login&lt;br /&gt;- password&lt;br /&gt;- pasword_repeat&lt;br /&gt;- email&lt;br /&gt;&lt;br /&gt;This is a pretty standard registration form. Naturally we&apos;d have to validate input coming from this form:&lt;br /&gt;- login has to be 4-16 symbols in length&lt;br /&gt;- password has to be 4-16 symbols in length&lt;br /&gt;- password has to be the same as password_repeat&lt;br /&gt;- email has to be a valid email address&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://erlyweb.org/doc/erlyweb_forms.html#validate-3&quot;&gt;Erlyweb&apos;s validation functions&lt;/a&gt; cant cope with this. My function can :)&lt;br /&gt;&lt;br /&gt;Suppose you have a function called &lt;code&gt;process_signup&lt;/code&gt;, which accepts the &lt;code&gt;yaws_arg&lt;/code&gt; record. Then the validation will look like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code lang=&quot;erlang&quot;&gt;process_signup(A) -&amp;gt;
	F = fun(A, Field) -&amp;gt;
		{ok, Val} = yaws_api:postvar(A, Field),
		L = string:len(Val),
		if
			L &amp;lt; 4 orelse L &amp;gt; 16 -&amp;gt;
				{Field, length};
			true -&amp;gt;
				{}
			end
	end,
	EmailCheck = fun(Args, Field2) -&amp;gt;
		{ok, Email} = yaws_api:postvar(Args, Field2),
		Match = regexp:match(Email, &quot;^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+&quot;),
		Match /= nomatch
	end,

	%% magic is here:
	buktu_form:validate(A, [
		{login, F},
		{email, EmailCheck},
		{password, [{&apos;=&apos;, password_repeat}, F]}
	]).
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If we don&apos;t input any field at all, we&apos;ll get back the following list:&lt;br /&gt;&lt;pre&gt;[{login,invalid_field},
 {email,invalid_field},
 {password,[{invalid_fields,[password,password_repeat]},
            invalid_field]}]
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If we input values that don&apos;t match our criteria, we&apos;ll get:&lt;br /&gt;&lt;pre&gt;[{login,length},
 {email,invalid_value},
 {password,[{not_equal,password_repeat},
            length]}]
&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The callback function that you can pass can return the following:&lt;ul&gt;&lt;br /&gt;&lt;li&gt; a tuple &lt;code&gt;{FieldName, Error}&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;true&lt;/code&gt; if the field is validated and &lt;code&gt;false&lt;/code&gt; otherwise (then the validation function will return &lt;code&gt;{FieldName, invalid_value}&lt;/code&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt; any value &lt;code&gt;Value&lt;/code&gt; which will be transformed into &lt;code&gt;{FieldName, Value}&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; if any of the fields in the rule don&apos;t exist or are empty, for each such rule the validation function will return:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;invalid_field&lt;/code&gt; if the field is compared against a value&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;{invalid_fields, [field1, field2]}&lt;/code&gt; if the field is compared against another field&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If you need to bind several rules to a field, pass a list of rules. If you just need to check if a field exists, pass in a tuple containing the field&apos;s name:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Does the field exist?&lt;br /&gt;&lt;code&gt;{field_name}&lt;/code&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Compare a field &lt;code&gt;field_name&lt;/code&gt; to field &lt;code&gt;field2_name&lt;/code&gt; (you can use &lt;code&gt;&apos;=&apos;, &apos;/=&apos;, &apos;&amp;lt;&apos;, &apos;=&amp;lt;&apos;, &apos;&amp;gt;&apos;, &apos;&amp;gt;=&apos;&lt;/code&gt; )&lt;br /&gt;&lt;code&gt;{field_name, {&apos;=&apos;, field2_name}}&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Compare a field to any value: &lt;br /&gt;&lt;code&gt;{field_name, {&apos;=&apos;, Value}}&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use a callback function (function/2, first parameter is yaws_arg, the second is the field&apos;s name). The function can be a lambda or any function of any module in the form of &lt;code&gt;module:function/2&lt;/code&gt; or &lt;code&gt;{module, function}&lt;/code&gt;&lt;br /&gt;&lt;code&gt;{field_name, F}&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use a callback function with an additional value (function/3,first parameter is yaws_arg, the second is the field&apos;s name, the third is the value). The function can be a lambda or any function of any module in the form of &lt;code&gt;module:function/3&lt;/code&gt; or &lt;code&gt;{module, function}&lt;/code&gt;&lt;br /&gt;&lt;code&gt;{field_name, {F, Value}}&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The validation function returns a &lt;code&gt;proplist&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;[{FieldName(), Errors()}]&lt;/pre&gt;&lt;br /&gt;where&lt;br /&gt;&lt;pre&gt;&lt;code&gt;FieldName() = atom()
Errors() = Error() | [Error()]
Error() = user_defined_values | absent | invalid_value | 
          invalid_field | {invalid_fields, [FieldName(), FieldName()]} |
          ComparisonError()
ComparisonError() = {not_equal, value_or_field} | {equal, value_or_field} |
                    {not_greater, value_or_field} | {not_less, value_or_field} |
                    {not_greater_or_equal, value_or_field} | {not_less_or_equal, value_or_field} |
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/code&gt;</description>
  <comments>http://community.livejournal.com/en_dmitriid/6523.html</comments>
  <category>erlyweb</category>
  <category>erlang</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/6383.html</guid>
  <pubDate>Thu, 06 Mar 2008 15:27:24 GMT</pubDate>
  <title>Apple...</title>
  <link>http://community.livejournal.com/en_dmitriid/6383.html</link>
  <description>&lt;a href=&quot;http://pics.livejournal.com/dmitriid/pic/000014zk/&quot;&gt;&lt;img src=&quot;http://pics.livejournal.com/dmitriid/pic/000014zk/s320x240&quot; width=&quot;320&quot; height=&quot;240&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;there it is.... quite unusual, but there is no way back...</description>
  <comments>http://community.livejournal.com/en_dmitriid/6383.html</comments>
  <category>apple</category>
  <lj:mood>accomplished</lj:mood>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/6014.html</guid>
  <pubDate>Fri, 24 Aug 2007 07:44:46 GMT</pubDate>
  <title>Somebody stop me</title>
  <link>http://community.livejournal.com/en_dmitriid/6014.html</link>
  <description>Or shoot me before I suffer too long :)&lt;br /&gt;&lt;br /&gt;I&apos;ve managed to get one of the oldest Firefox bugs going: &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=69230&quot;&gt;https://bugzilla.mozilla.org/show_bug.cgi?id=69230&lt;/a&gt; (see &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=69230#c86&quot;&gt;comment 86&lt;/a&gt;). I have know idea what to do with it now :) And there&apos;s the possibility that I will have to compile Mozilla from the source...&lt;br /&gt;&lt;br /&gt;&quot;Tell my wife and children that I love them...&quot;  :))</description>
  <comments>http://community.livejournal.com/en_dmitriid/6014.html</comments>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/5806.html</guid>
  <pubDate>Tue, 21 Aug 2007 13:39:02 GMT</pubDate>
  <title>Erlang Bit Syntax</title>
  <link>http://community.livejournal.com/en_dmitriid/5806.html</link>
  <description>I&apos;ve decided to see whether all is as well with Erlang&apos;s bit syntax as advertised..
&lt;br /&gt;&lt;br /&gt;
A friend of mine has been struggling with SOny&apos;s OMA format which is being used in Sony&apos;s players. The only feature this format has that distinguishes it from &quot;normal&quot; formats is its lack of documentation and whatever documentation there is differs significantly from whatever actual files have to offer :)&lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;
&lt;br /&gt;&lt;br /&gt;
There are some good folk out there and they&apos;ve reverse engineered the format and wrote a Java program to maniplate it. The program is available here: &lt;a href=&quot;http://dmitriid.com/files/projects/erlang/OMA.zip&quot;&gt;http://dmitriid.com/files/projects/erlang/OMA.zip&lt;/a&gt;. The program is accompanied by documentation on Sony players&apos; directory structure and, what&apos;s more important, on OM file format as well.
&lt;br /&gt;&lt;br /&gt;
You can see the OMA header format in this file: &lt;a href=&quot;http://dmitriid.com/files/projects/erlang/OMA.html&quot;&gt;http://dmitriid.com/files/projects/erlang/OMA.html&lt;/a&gt;. It doesn&apos;t look to horrible, does it? Let&apos;s see how Erlang handles it.
&lt;br /&gt;&lt;br /&gt;
The first obstacle comes from the sample file that comes with the application (&lt;code&gt;trunk/dist/OMGAUDIO/10F00/10000001.OMA&lt;/code&gt;). The spec says it has to start with
&lt;pre style=&quot;border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&quot;E&quot; &quot;A&quot; &quot;3&quot; 3 0 0 0 0 17  76 &quot;T&quot; &quot;I&quot; &quot;T&quot; &quot;2&quot; 0 0
&lt;/code&gt;&lt;/pre&gt;
You wish. In reality it starts with
&lt;pre style=&quot;border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&quot;e&quot; &quot;a&quot; &quot;3&quot; 3 0 0 0 0 17 &quot;v&quot; &quot;G&quot; &quot;E&quot; &quot;O&quot; &quot;B&quot; 0 0
&lt;/code&gt;&lt;/pre&gt;
And there&apos;s lots of info before we reach TIT2. Oh well, hex-editor to the rescue. The files does contain the tags shown in the &lt;a href=&quot;http://dmitriid.com/files/projects/erlang/OMA.html&quot;&gt;spec&lt;/a&gt;. However, they are placed differently and there&apos;s a bunch of other, unknown tags. Whatever shall we do? I propose moving byte by byte until we reach tags that we know of or the end of the header.
&lt;br /&gt;&lt;br /&gt;
I&apos;ll tell you from the start that I cheated. I don&apos;t read the codec info from the header, I stop as soon as I reach
&lt;pre style=&quot;border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&quot;E&quot; &quot;A&quot; &quot;3&quot; 2 0 60 ff ff
&lt;/code&gt;&lt;/pre&gt;

&lt;strong&gt;So, the code&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
Open the file and read data from it
&lt;pre style=&quot;font-size: 12pt; border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000;&quot;&gt;parse_header(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;file:open&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, [read, binary, raw]) &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;of&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        {ok, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;} -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            {ok, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Header&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;} = &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;file:pread&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;#0c60),&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;H&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; read_header(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Header&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;of&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                    {&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, invalid_header};&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Data&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                    &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Data&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;file:close&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;),&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;H&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            {&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, file_cannot_be_opened}&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
Well, that was easy. Open the file. Read it. Call internal &lt;code&gt;read_header&lt;/code&gt; function to actuall parse the header and return the value that we receive from the function.
&lt;br /&gt;&lt;br /&gt;
The &lt;code&gt;read_header&lt;/code&gt; function couldn&apos;t be simpler
&lt;pre style=&quot;font-size: 12pt; border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000;&quot;&gt;read_header(&amp;lt;&amp;lt;$e, $a, $3, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary&amp;gt;&amp;gt;) -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Data&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; = decode_header(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, []),&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Data&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;read_header(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
It couldn&apos;t be simpler because of the pattern-match. If the chunk of data that comes in starts with
&lt;pre style=&quot;border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&quot;e&quot; &quot;a&quot; &quot;3&quot;
&lt;/code&gt;&lt;/pre&gt;
it&apos;s passed to the upper function. Otherwise, the lower function is called.
&lt;br /&gt;&lt;br /&gt;
The actual parsing is contained in several &lt;code&gt;decode_header&lt;/code&gt; functions which parse a single tag at a time. Here&apos; an example:
&lt;pre style=&quot;font-size: 12pt; border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;% Title&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;decode_header(&amp;lt;&amp;lt;$&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, $&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;I&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, $&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, $2, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/integer-unit:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary&amp;gt;&amp;gt;, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) -&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;TitleLength&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Title&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;TitleLength&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary&amp;gt;&amp;gt; = &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        decode_header(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, [&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;|{title, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Title&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
What happens here? Keep &lt;a href=&quot;http://dmitriid.com/files/projects/erlang/OMA.html&quot;&gt;the spec&lt;/a&gt; before your eyes.
&lt;br /&gt;&lt;br /&gt;
Here we go. The song title is stored as follows
&lt;pre style=&quot;font-size: 12pt; border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;T I T 2 0 0 Var1 Var1 0 0 2 TitleString
&lt;/code&gt;&lt;/pre&gt;
where &lt;code&gt;TitleString&lt;/code&gt; is &lt;code&gt;[0x0 String]&lt;/code&gt;. That&apos;s exactly what we&apos;ve specified in the pattern:
&lt;pre style=&quot;font-size: 12pt; border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;T        $&lt;span style=&quot;color: #008000;&quot;&gt;T&lt;/span&gt;
I        $&lt;span style=&quot;color: #008000;&quot;&gt;I&lt;/span&gt;
T        $&lt;span style=&quot;color: #008000;&quot;&gt;T&lt;/span&gt;
2        $&lt;span style=&quot;color: #008000;&quot;&gt;2&lt;/span&gt;
0        &lt;span style=&quot;color: #008000;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary&lt;/span&gt;            simply skip the two zeroes
0
Var1     &lt;span style=&quot;color: #008000;&quot;&gt;Var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/integer-unit:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;8&lt;/span&gt;  a number containd in two bytes
Var1
0        &lt;span style=&quot;color: #008000;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary&lt;/span&gt;            simply skip 0 0 2 0
0
2
0
TitleString &lt;span style=&quot;color: #008000;&quot;&gt;Rest&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
All we have to do now is get the title from &lt;code&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest&lt;/span&gt;&lt;/code&gt;. Empirically I&apos;ve guessed that the length of this title in our case is &lt;code&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;/code&gt;. Having decided on that, we can get the title using pattern matching, again:
&lt;pre style=&quot;font-size: 12pt; border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;TitleLength&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Title&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;TitleLength&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/binary&amp;gt;&amp;gt; = &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Rest&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
This way all we have to do is to parse all the remaining tags according to the rules and test them against a real file. The real file may give us a headache because it doesn&apos;t confirm to the spec (albeit informal) and adds several new and unknown tags. That is why we need to augment &lt;code&gt;decode_header&lt;/code&gt; with:
&lt;pre style=&quot;font-size: 12pt; border-left: 4px solid gray; padding: 5px;&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000;&quot;&gt;decode_header(&amp;lt;&amp;lt;&amp;gt;&amp;gt;, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;decode_header(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Bin&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) -&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;NewBin&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;} = &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;split_binary&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;Bin&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;),&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    decode_header(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;NewBin&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
We move forward byte by byte. If we match a known tag, it is caught by the corresponding &lt;code&gt;decode_header&lt;/code&gt;. If we&apos;ve reached the end of the header, this will be natched by &lt;code&gt;decode_header(&amp;lt;&amp;lt;&amp;gt;&amp;gt;, L)&lt;/code&gt;. Otherwise we move forward by one more byte and repeat the steps nce again.
&lt;br /&gt;&lt;br /&gt;
The entire file is available here: &lt;a href=&quot;http://erltag.googlecode.com/svn/trunk/src/oma.erl&quot;&gt;http://erltag.googlecode.com/svn/trunk/src/oma.erl&lt;/a&gt;. If you want to practice, download this file: &lt;a href=&quot;http://erltag.googlecode.com/files/erltag-release.zip&quot;&gt;http://erltag.googlecode.com/files/erltag-release.zip&lt;/a&gt;(6.1 MB). You can find the sample audiofile in the test folder.
&lt;br /&gt;&lt;br /&gt;
By the way. The code doesn&apos;t pretend to be the most effecient and correct way of writing Erlang code. Most likely the code is rather opposite of that :)
</description>
  <comments>http://community.livejournal.com/en_dmitriid/5806.html</comments>
  <category>erlang</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/5581.html</guid>
  <pubDate>Tue, 31 Jul 2007 11:44:38 GMT</pubDate>
  <title>Programming Erlang</title>
  <link>http://community.livejournal.com/en_dmitriid/5581.html</link>
  <description>It has finally arrived!&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://s3.amazonaws.com/mamut-site-images/1273.800x600.jpg&quot;&gt;&lt;img src=&quot;http://s3.amazonaws.com/mamut-site-images/1273.300x225.jpg&quot; alt=&quot;Programming Erlang&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://s3.amazonaws.com/mamut-site-images/1274.800x600.jpg&quot;&gt;&lt;img src=&quot;http://s3.amazonaws.com/mamut-site-images/1274.300x225.jpg&quot; alt=&quot;Programming Erlang&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://s3.amazonaws.com/mamut-site-images/1275.800x600.jpg&quot;&gt;&lt;img src=&quot;http://s3.amazonaws.com/mamut-site-images/1275.300x225.jpg&quot; alt=&quot;Programming Erlang&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It arrived at Moldova on Juky 21st. It got out of customs on July 25th. And it is only today that I finally noticed the invitation to pick it up at my local post office. :)&lt;br /&gt;&lt;br /&gt;Hurrah!&lt;br /&gt;&lt;br /&gt;Now if I only could find time to study it...</description>
  <comments>http://community.livejournal.com/en_dmitriid/5581.html</comments>
  <category>erlang</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/5342.html</guid>
  <pubDate>Wed, 18 Jul 2007 15:12:18 GMT</pubDate>
  <title>Keep&apos;em languages coming!</title>
  <link>http://community.livejournal.com/en_dmitriid/5342.html</link>
  <description>Past Friday I got myself acquainted to &lt;a href=&quot;http://python.org/&quot;&gt;Python&lt;/a&gt;.
&lt;br /&gt;&lt;br /&gt;
Different people view Python as &quot;nothing to learn&quot; or as &quot;if only I had time to learn&quot; or even as &quot;very difficult to learn&quot;.
&lt;br /&gt;&lt;br /&gt;
I had to learn it quick for a very simple reason. I have lots of photos taken at different resolutions. I need to resize them to different sizes (much like &lt;a href=&quot;http://flickr.com&quot;&gt;Flickr&lt;/a&gt; does), create several thumbnails of each image, upload them to a host (&lt;a href=&quot;http://s3.amazonaws.com/&quot;&gt;Amazon S3&lt;/a&gt;) and load information on uploaded images to a database.
&lt;br /&gt;&lt;br /&gt;
The process must be automated, of course.
&lt;br /&gt;&lt;br /&gt;
It all started when I convinced myself that &lt;a href=&quot;http://www.pythonware.com/products/pil/&quot;&gt;Python Imaging Library&lt;/a&gt; is the best library to manipulate images. Indeed:
&lt;br /&gt;&lt;br /&gt;
&lt;div class=&quot;python&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; Image&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;im = Image.&lt;span class=&quot;kw2&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&apos;path/to/image&apos;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;im.&lt;span class=&quot;me1&quot;&gt;thumbnail&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;800&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;, Image.&lt;span class=&quot;me1&quot;&gt;ANTIALIAS&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;im.&lt;span class=&quot;me1&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&apos;path/to/image&apos;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
The line with &lt;code&gt;im.thumbnail((800, 800), Image.ANTIALIAS)&lt;/code&gt; is absolute genius. If your image is, say, 1024х768px, then what you get in the end is not a skewed 800х800px, but a proportional 800x600px.
&lt;br /&gt;&lt;br /&gt;
Combined with &lt;a href=&quot;http://mysql-python.sourceforge.net/&quot;&gt;MySQLDb&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/boto/&quot;&gt;Boto&lt;/a&gt; this yields a very easy solution to my task. However, that&apos;s not the point.
&lt;br /&gt;&lt;br /&gt;
As it turns out, getting to know many languages (even superficially) may give you a huge head start in learning a new programming language. I&apos;ve had an overview or, sometimes, more than an overview of such languages as &lt;a href=&quot;http://en.wikipedia.org/wiki/Lisp_programming_language&quot;&gt;Lisp&lt;/a&gt;, &lt;a href=&quot;http://www.haskell.org/&quot;&gt;Haskell&lt;/a&gt;, &lt;a href=&quot;http://www.erlang.org/&quot;&gt;Erlang&lt;/a&gt;... How does that help me with Python? Well, I got an imeddiate understanding of the following:
&lt;br /&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 10pt; color: gray; border: 1px solid #efefef; padding: 2px&quot;&gt;&lt;strong&gt;Note:&lt;/strong&gt; I can bear no responsibility for Haskell codes in the examples :)&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Tuples and destructuring assignment&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
A tuple is a fixed-length list. This list may contain elements that are very different in nature:
&lt;div class=&quot;python&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# Python tuple&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&apos;hello&apos;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- Haskell tuple&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &quot;hello&quot;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% Erlang tuple&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;br0&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &apos;hello&apos;&lt;span class=&quot;br0&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
Looks similar, doesn&apos;t it? :)
&lt;br /&gt;&lt;br /&gt;
Let now get data out of our tuples:
&lt;div class=&quot;python&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# Python&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# А will contain 1&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# В will contain 2&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# С will contain &apos;hello&apos;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;br0&quot;&gt;&lt;/span&gt;A, B, C&lt;span class=&quot;br0&quot;&gt;&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &apos;hello&apos;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- Haskell&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- a will contain 1&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- b will contain 2&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- c will contain &apos;hello&apos;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;a, b, c&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &quot;hello&quot;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% Erlang&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% А will contain 1&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% В will contain 2&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% С will contain &apos;hello&apos;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;br0&quot;&gt;{&lt;/span&gt;A, B, C&lt;span class=&quot;br0&quot;&gt;}&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &apos;hello&apos;&lt;span class=&quot;br0&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
Certainly, the principles of theses examples are very different. Haskell and Erlang use pattern matching that Python doesn&apos;t have. However, it looks very similar and is very easy to understand once you know the other examples. PHP, by the way, has a similar thing:
&lt;div class=&quot;php-brief&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// А will contain 1&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// В will contain 2&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// С will contain &apos;hello&apos;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;list&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$A&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$B&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$C&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt; = &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&apos;hello&apos;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
This, of course, is very different and the inner workings are absolutely different :) One thing about this is quite peculiar, though. Once you get used to these sorts of destructuring assignments, you start using PHP&apos;s &lt;code&gt;list&lt;/code&gt; and Python&apos;s tuples much more often. Because it&apos;s so convenient.
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Named parameters&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
I once &lt;a href=&quot;http://community.livejournal.com/en_dmitriid/2345.html&quot;&gt;talked about named parameters&lt;/a&gt;. As it turns out, Pythons has them.
&lt;div class=&quot;python&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# define a function&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;def&lt;/span&gt; myfunc&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;param=&lt;span class=&quot;st0&quot;&gt;&apos;&apos;&lt;/span&gt;, another_param=&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;print&lt;/span&gt; param, another_param&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# call the function&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# will print hello 5&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;myfunc&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;another_param=&lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, param=&lt;span class=&quot;st0&quot;&gt;&apos;hello&apos;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# will print hello 1&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;myfunc&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;param=&lt;span class=&quot;st0&quot;&gt;&apos;hello&apos;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# will print 1&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;myfunc&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Anonymous functions (lambdas)&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;div class=&quot;python&quot;&gt;&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# Python&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# define a list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;256&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;-3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# get only evens out of the list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li_even = &lt;span class=&quot;kw2&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;lambda&lt;/span&gt; item: item % &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt; == &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;, li&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
Very similar to code in other languages:
&lt;br /&gt;&lt;br /&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- Haskell&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- define a list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;256&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;-3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- get only evens out of the list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li_even = &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:filter&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;filter&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;\item -&amp;gt; &lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:mod&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;mod&lt;/span&gt;&lt;/a&gt; item &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt; == &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt; li&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% Erlang&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% define a list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;Li = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;256&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;-3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% get only evens out of the list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;Li_even = &lt;span class=&quot;kw3&quot;&gt;lists:filter&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;br1&quot;&gt;(&lt;/span&gt;Item&lt;span class=&quot;br1&quot;&gt;)&lt;/span&gt; -&amp;gt; Item rem 2 == 0 &lt;span class=&quot;kw4&quot;&gt;end&lt;/span&gt;, Li&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;List comprehensions&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
Remember how we used to define lists in mathematics? For instance:
&lt;div class=&quot;python&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;S = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;M = &lt;span class=&quot;br0&quot;&gt;{&lt;/span&gt;x | x in S, x even&lt;span class=&quot;br0&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
M is all x&apos;s where x belongs to S and x is even. Nice languages have ways to define lists in a very mathematical way. This is called list comprehensions. One downside to Python&apos;s comprehensions is the syntax. Here are previous examples rewritten to use list comprehensions instead of lambdas:
&lt;br /&gt;&lt;br /&gt;
&lt;div class=&quot;python&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# Python&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# define a list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;256&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;-3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;# get only evens out of the list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li_even = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;x &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; x &lt;span class=&quot;kw1&quot;&gt;in&lt;/span&gt; li &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; x % &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt; == &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- Haskell&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- define a list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;256&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;-3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- get only evens out of the list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;li_even = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;x | x &amp;lt;- li, &lt;span class=&quot;br0&quot;&gt;(&lt;/span&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:mod&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;mod&lt;/span&gt;&lt;/a&gt; x &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;)&lt;/span&gt; == &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;haskell&quot;&gt;
&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% Erlang&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% define a list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;Li = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;256&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;-3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;co1&quot;&gt;%% get only evens out of the list&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;Li_even = &lt;span class=&quot;br0&quot;&gt;[&lt;/span&gt;X || X &amp;lt;- Li, X &lt;span class=&quot;kw3&quot;&gt;rem&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt; == &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/div&gt;

&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Anyhow, thanks to other languages the new language (a more or less mainstream language, not &lt;a href=&quot;http://en.wikipedia.org/wiki/K_(programming_language)#Examples&quot;&gt;K&lt;/a&gt; :)) ) is not just easy, it&apos;s extreamly easy and can be learned in, say, 15 minutes.
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 10pt; color: gray; border: 1px solid #efefef; padding: 2px&quot;&gt;&lt;strong&gt;Update:&lt;/strong&gt; Corrections to Haskell code. Thanks, &lt;span class=&apos;ljuser&apos; lj:user=&apos;deni_ok&apos; style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://deni-ok.livejournal.com/profile&apos;&gt;&lt;img src=&apos;http://p-stat.livejournal.com/img/userinfo.gif&apos; alt=&apos;[info]&apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;http://deni-ok.livejournal.com/&apos;&gt;&lt;b&gt;deni_ok&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; &lt;/div&gt;</description>
  <comments>http://community.livejournal.com/en_dmitriid/5342.html</comments>
  <category>python</category>
  <category>haskell</category>
  <category>erlang</category>
  <category>php</category>
  <category>general</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/4916.html</guid>
  <pubDate>Mon, 28 May 2007 11:04:35 GMT</pubDate>
  <title>Pragmatic Erlang</title>
  <link>http://community.livejournal.com/en_dmitriid/4916.html</link>
  <description>Almost 60 dollars left my pocket to get &lt;a href=&quot;http://www.pragmaticprogrammer.com/titles/jaerlang/&quot;&gt;Joe Armstrong. &quot;Programming Erlang. Software for a Concurrent World&quot;&lt;/a&gt;. It&apos;s finally mine! As a PDF only so far. I&apos;ll get to reading it eventually......&lt;br /&gt;&lt;br /&gt;Yeah, baby! :)</description>
  <comments>http://community.livejournal.com/en_dmitriid/4916.html</comments>
  <category>erlang</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/4625.html</guid>
  <pubDate>Fri, 29 Dec 2006 13:39:55 GMT</pubDate>
  <title>NY</title>
  <link>http://community.livejournal.com/en_dmitriid/4625.html</link>
  <description>HAPPY NEW YEAR TO ALL FRIENDS AND ENEMIES!!!</description>
  <comments>http://community.livejournal.com/en_dmitriid/4625.html</comments>
  <category>misc</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/4599.html</guid>
  <pubDate>Sun, 08 Oct 2006 08:37:35 GMT</pubDate>
  <title>Orcas official site</title>
  <link>http://community.livejournal.com/en_dmitriid/4599.html</link>
  <description>Orcas has been moved to &lt;a href=&quot;http://orcas.dmitriid.com/&quot;&gt;http://orcas.dmitriid.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Project description etc etc can be accessed via project wiki at &lt;a href=&quot;http://orcas.dmitriid.com/wiki&quot;&gt;http://orcas.dmitriid.com/wiki&lt;/a&gt;</description>
  <comments>http://community.livejournal.com/en_dmitriid/4599.html</comments>
  <category>erlang</category>
  <category>orcas</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/4339.html</guid>
  <pubDate>Wed, 04 Oct 2006 09:01:21 GMT</pubDate>
  <title>Refactoring, pattern matching, function guards and Erlang</title>
  <link>http://community.livejournal.com/en_dmitriid/4339.html</link>
  <description>I&apos;m still late on my &lt;a href=&quot;http://community.livejournal.com/en_dmitriid/2345.html&quot;&gt;promise&lt;/a&gt; to talk about pattern matching even though today&apos;s post is related to patern matching.&lt;br /&gt;&lt;br /&gt;In brief here is what pattern matching all about. The all-knowing &lt;a href=&quot;http://en.wikipedia.org/wiki/Pattern_matching&quot;&gt;Wikipedia&lt;/a&gt; defines pattern matching as &lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;the act of checking for the presence of the constituents of rigidly specified pattern&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;What does this mean though? This means that when a function (especially in dynamically typed languages) accepts parameters of different kinds/types we can define this function like this::&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
fun([H|T]) -&amp;gt;
    do_smth();

fun({a, tuple}) -&amp;gt;
    do_smth_else();

fun(value) -&amp;gt;
   do_a_third_thing();

fun(DefaultValue) -&amp;gt;
   do_default_thing().
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;What happens in the code above?&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;1. First function accepts a list/array as its parameter. The list consists of a Head and a Tail. So, if we pass [1, 2, 3, 4] to this function, the variable H will contain 1 and variable T will contain [2, 3, 4]&lt;br /&gt;&lt;br /&gt;2. The second function accepts a tuple, that consists of two immutable values, &quot;a&quot; and &quot;tuple&quot;&lt;br /&gt;&lt;br /&gt;3. The third function accepts an immutable value of &quot;value&quot;&lt;br /&gt;&lt;br /&gt;4. The fourth function accepts everything rejected by the first three functions&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;So. If we call a function like this:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
fun([2, 5, 72]).
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;we will trigger the first function, since it accepts an array/list.&lt;br /&gt;&lt;br /&gt;However, if we call the function like so: &lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
fun({another, tuple}).
 &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;we will trigger the fourth function. Why? Because even though we pass a tuple, the third function accepts only one tuple, {a, tuple} whereas we pass a different tuple, {another, tuple}.&lt;br /&gt;&lt;br /&gt;So what&apos;s refactoring got to do with all this? And what&apos;s function guards?&lt;br /&gt;&lt;br /&gt;A couple of things about function guards. Consider the ubiquitous Fibonacci function. First, pattern matching:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
fib(1) -&amp;gt; 1; 

fib(2) -&amp;gt; 1; 

fib(X) -&amp;gt; fib(X-1) + fib(X-2).
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;Now, function guards:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt; 
fib(X) when X =&amp;lt; 3 -&amp;gt; 1; 

fib(X) -&amp;gt; fib(X-1) + fib(X-2).
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;The first line reads: &quot;If X is less than 3, return 1&quot;. &lt;br /&gt;&lt;br /&gt;Guards can check for a wide range of conditions, including such thnigs as is_list(X), is_tuple(X) etc. They can also be stacked using such keywords as &quot;and&quot;, &quot;or&quot; etc. More on them in forecoming topics. Back to the topic at hand.&lt;br /&gt;&lt;br /&gt;A question &lt;a href=&quot;http://gzip.rsdn.ru/Forum/Message.aspx?mid=2113522&amp;amp;only=1&quot;&gt;was raised over at RSDN&lt;/a&gt; with regard to implementation of the Factory pattern. For instance, in creating a wrapper for various database connections. The following С++ code was given as an example:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
class Driver
{
public:
  virtual void connect() = 0;
};

class MysqlDriver : public Driver {}; //implements connect() using some mysql API calls.
class OracleDriver : public Driver {}; //implements connect() using some oracle API calls.
 &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;And, finally,  &lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
class DriverFactory
{
public:
  static Driver * createDriver( string name ) //creates necessary driver
  {
    Driver * driver = 0;
    if(&quot;mysql&quot; == name ) driver = new MysqlDriver();
    else if( &quot;oracle&quot; == name ) driver = OracleDriver();
    else throw 1;
    return driver;
  }
};
 &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;The key to this factory, is of course the following:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
if(&quot;mysql&quot; == name ) driver = new MysqlDriver();
    else if( &quot;oracle&quot; == name ) driver = OracleDriver();
    else throw 1;
 &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;Ok. Let&apos;s rewrite it using Erlang.&lt;br /&gt;&lt;br /&gt;First that springs to mind is the obvious line-by-line translation of the C++ code:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
start(Driver) -&amp;gt;
    case Driver of
        mysql -&amp;gt;
            % connection happens here
            {};
        mnesia -&amp;gt;
            % connection happens here
            {};
        odbc -&amp;gt;
            % connection happens here
            {}
    end.
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;It&apos;s clear that you would call the function as follows:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
start(mysql).
start(mnesia).
start(odbc).
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;Note that the &quot;case&quot; construct in Erlang also employs pattern matching.&lt;br /&gt;&lt;br /&gt;What if connection i a bulky piece of code spanning 10-20 lines? We could employ function guards of course::&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt; 
start(Driver) when Driver == mysql -&amp;gt;
    % connection happens here
    {};

start(Driver) when Driver == mnesia -&amp;gt;
    % connection happens here
    {};

start(Driver) when Driver == odbc -&amp;gt;
    % connection happens here
    {}.
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;This is more like it. Function call hasn&apos;t chaned a bit: &lt;code&gt;start(&lt;i&gt;driver_name&lt;/i&gt;)&lt;/code&gt;. Guards, however, are not expressive enough. You have to read the definition of the function and only after that your eye cathes the guard. Is there a better way to do this? Of course!&lt;br /&gt;&lt;br /&gt;Recall that pattern matching involves a &quot;&lt;b&gt;rigidly defined&lt;/b&gt; pattern&quot;. What&apos;s more rigid than&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
start(mysql) -&amp;gt;
    % connection happens here
    {};

start(mnesia) -&amp;gt;
    % connection happens here
    {};

start(odbc) -&amp;gt;
    % connection happens here
    {};
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;We can improve on our example and introduce options that will be passed to the connection code:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;
start(Driver) -&amp;gt;
    start(Driver, []).
        
start(mysql, Options) -&amp;gt;
    % connection happens here
    {};
    
start(mnesia, Options) -&amp;gt;
    % connection happens here
    {};
    
start(odbc, Options) -&amp;gt;
    % connection happens here
    {};
    
start(_, _) -&amp;gt;
    {error, driver_not_supported}.
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;Last lines simply states that for any other type of connection we through an error. Underscore means &quot;any variable&quot;, a sort of &quot;joker&quot;.&lt;br /&gt;&lt;br /&gt;That&apos;s a part of what, to me, is the &quot;Erlang Way&quot;. Very shortly and quite inaccurately this could be defined as: focus on what you need. A slight improvement of this definition is described in the concept of &quot;aggressve programming&quot;. See. &lt;a href=&quot;http://www.erlang.se/doc/programming_rules.shtml#HDR11&quot;&gt;Erlang programming rules&lt;/a&gt; for a description. &lt;br /&gt;&lt;br /&gt;That is, a program/module/function should do only the things it&apos;s meant to do. Under all other circumstances it should fail specifying why it failed, because it really should be the problem of the person who decided to (ab)use the program/module/function in the wrong way. As a result you end up with a small number of functions/modules which only do what they are meant to do. And this is quite handy&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.erlang.se/doc/programming_rules.shtml&quot;&gt;The same page&lt;/a&gt; lists other things in the &quot;Erlang way&quot;, in particular:&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;- top-down programming (you start with abstractions and work towards details), &lt;br /&gt;- &quot;make it work correctly now and worry about otimizations later&quot;, &lt;br /&gt;- principle of least astonishment (the system must behave predictably)&lt;br /&gt;- &quot;aggressive&quot; programming etc.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;Actually, this approach can be used - and is used! - in mainstream languages such as C++, Java, C#. However, in order to employ this approach in these languages, you need experience (quite a lot of it some times - a nod to C++). Erlang, on the other hand, encourages this approach right from the start.&lt;br /&gt;&lt;br /&gt;I general, I&apos;m not going to give up on Erlang in the forseeable future :) Unless it&apos;s in favour of Ne,erle, perhaps :))</description>
  <comments>http://community.livejournal.com/en_dmitriid/4339.html</comments>
  <category>erlang</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/3973.html</guid>
  <pubDate>Mon, 25 Sep 2006 07:23:17 GMT</pubDate>
  <title>erlsoap</title>
  <link>http://community.livejournal.com/en_dmitriid/3973.html</link>
  <description>Opensource projects, eh? They make you involve in all sorts of things :) Thanks to the ever unpredictable Lady Luck, Anton Fedorov decided to bring the &lt;a href=&quot;http://community.livejournal.com/ru_dmitriid/3968.html&quot;&gt;aforementioned erlsoap library&lt;/a&gt; up to date. &lt;br /&gt;&lt;br /&gt;So the battle ensued between me and the shiny new 0.4 version of erlsoap. This version decided it didn&apos;t like &lt;a href=&quot;http://rsdn.ru/ws/JanusAT.asmx&quot;&gt;RSDN&apos;s webservice&lt;/a&gt;. After some fruitful discussion with Anton a new, 0.4.1, version of erlsoap appeared. This version, however, didn&apos;t suit &lt;a href=&quot;http://code.google.com/u/qrilka/&quot;&gt;qrilka&lt;/a&gt; in the least :)) The problem lay with the inets library distributed with Erlang and used by erlsoap. Inets, as it turned out, doesn&apos;t support proxy authentication.&lt;br /&gt;&lt;br /&gt;So what&apos;s a developer got to do? I geared up  and went to hunt... ehm... to add support for a more advanced ibrowse library. As a result, I&apos;ve officially &lt;a href=&quot;http://forum.trapexit.org/viewtopic.php?p=21672#21672&quot;&gt;added my first patch to an opensource project&lt;/a&gt; which even brought me a mention in the soapclient module in erlsoap&apos;s new &lt;a href=&quot;http://forum.trapexit.org/download.php?id=15&quot;&gt;version 0.4.2&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now I&apos;m tuly happy :)</description>
  <comments>http://community.livejournal.com/en_dmitriid/3973.html</comments>
  <category>erlang</category>
  <category>orcas</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/3825.html</guid>
  <pubDate>Tue, 19 Sep 2006 13:41:51 GMT</pubDate>
  <title>The cavalry is coming!</title>
  <link>http://community.livejournal.com/en_dmitriid/3825.html</link>
  <description>Camrade &lt;a href=&quot;http://rsdn.ru/Users/Profile.aspx?uid=1546&quot;&gt;qrilka&lt;/a&gt; has shown interest in &lt;a href=&quot;http://code.google.com/p/orcas/&quot;&gt;Orcas&lt;/a&gt;. Right now we are not quite sure as to what is the best approach to SOAP in Erlang.&lt;br /&gt;&lt;br /&gt;Since &lt;a href=&quot;http://rsdn.ru/ws/JanusAT.asmx&quot;&gt;RSDN&apos;s webservice&lt;/a&gt; is quite small, one approach would be to implement all calls and parse all responses by hand. But that&apos;s boring, isn&apos;t it? :)&lt;br /&gt;&lt;br /&gt;Today I&apos;ve braced myself and went to war with &lt;a href=&quot;http://www.erlang-projects.org/Public/news/erlsoap_0.3/view&quot;&gt;erlsoap&lt;/a&gt;, which has been stagnating for the past two years. Well, you can check out the code &lt;a href=&quot;http://code.google.com/p/orcas/source&quot;&gt;yourself&lt;/a&gt;. The file is test_soap.erl, and you run it by &lt;table&gt;&lt;tr&gt;&lt;td bgcolor=&quot;gray&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;test_soap:run().&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;br /&gt;&lt;br /&gt;qrilka suggested that we use &lt;a href=&quot;http://yarivsblog.com/articles/tag/smerl&quot;&gt;Smerl&lt;/a&gt;. This still leaves quite a lot to do by hand. Anyway, tomorrow, time permitting, we&apos;ll take a look into the matter.</description>
  <comments>http://community.livejournal.com/en_dmitriid/3825.html</comments>
  <category>erlang</category>
  <category>orcas</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/3541.html</guid>
  <pubDate>Fri, 15 Sep 2006 14:45:33 GMT</pubDate>
  <title>Orcas</title>
  <link>http://community.livejournal.com/en_dmitriid/3541.html</link>
  <description>Well, I&apos;ve slowly started working on an offline client for RSDN.ru in Erlang.&lt;br /&gt;&lt;br /&gt;Here&apos;s the project page: &lt;a href=&quot;http://code.google.com/p/orcas/&quot;&gt;Orcas&lt;/a&gt;&lt;br /&gt;Here&apos;s &lt;a href=&quot;http://rsdn.ru/Forum/Message.aspx?mid=2112572&amp;amp;only=1&quot;&gt;anouncement of the fact&lt;/a&gt; on RSDN (in Russian)</description>
  <comments>http://community.livejournal.com/en_dmitriid/3541.html</comments>
  <category>projects</category>
  <category>rsdn</category>
  <category>erlang</category>
  <category>orcas</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/3294.html</guid>
  <pubDate>Mon, 04 Sep 2006 07:35:58 GMT</pubDate>
  <link>http://community.livejournal.com/en_dmitriid/3294.html</link>
  <description>Kosma Prutkov. Fruits of thought. # 66&lt;br /&gt;&lt;br /&gt;Many a thing we do not understand not because our reasoning is weak, but because we have no notion of them</description>
  <comments>http://community.livejournal.com/en_dmitriid/3294.html</comments>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/2884.html</guid>
  <pubDate>Mon, 21 Aug 2006 14:26:22 GMT</pubDate>
  <title>Dynamic languages rule</title>
  <link>http://community.livejournal.com/en_dmitriid/2884.html</link>
  <description>It seems to me that dynamic languages...That is, languages which have more dynamics built in... That is, nice languages to put it simply :)) Well, they rule. &lt;br /&gt;&lt;br /&gt;I&apos;ve been browsing Jakarta Commons&apos; source code using &lt;a href=&quot;http://www.koders.com/&quot;&gt;http://www.koders.com/&lt;/a&gt; (I actualy only needed their WordUtils in order to rewrite them in ColdFusion). An then I see &lt;a href=&quot;http://www.koders.com/java/fid81E5DE57AF2F1EFCA3D2A15B2F1D3B36005F7336.aspx&quot;&gt;Validate.java&lt;/a&gt;:&lt;br /&gt;&lt;pre style=&quot;background-color: #efefef&quot;&gt;
    public static void isTrue(boolean expression, String message, Object value) {
        if (expression == false) {
            throw new IllegalArgumentException(message + value);
        }
    }

    public static void isTrue(boolean expression, String message, long value) {
        if (expression == false) {
            throw new IllegalArgumentException(message + value);
        }
    }

    public static void isTrue(boolean expression, String message, double value) {
        if (expression == false) {
            throw new IllegalArgumentException(message + value);
        }
    }

    public static void isTrue(boolean expression) {
        if (expression == false) {
            throw new IllegalArgumentException(&quot;The validated expression is false&quot;);
        }
    }
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;:)) Static typing is the answer to everything they say, but at what cost? :))) I wonder if this could be rewritten... ColdFusion-style:&lt;br /&gt;&lt;pre style=&quot;background-color: #efefef&quot;&gt;
&amp;lt;cffunction name=&quot;isTrue&quot;&amp;gt;
    &amp;lt;cfargument name=&quot;expression&quot; type=&quot;boolean&quot; required=&quot;yes&quot;&amp;gt;    
    &amp;lt;cfargument name=&quot;message&quot; type=&quot;string&quot; required=&quot;no&quot;&amp;gt;
    &amp;lt;cfargument name=&quot;value&quot; type=&quot;any&quot; required=&quot;no&quot;&amp;gt;  
	
	&amp;lt;cfset msg=IIF(IsDefined(&apos;arguments.message&apos;), DE(arguments.message), DE(&quot;The validated expression is false&quot;))&amp;gt;
	&amp;lt;cfset v=IIF(IsDefined(&apos;arguments.value&apos;), DE(arguments.value), DE(&quot;&quot;))&amp;gt;
	
	&amp;lt;cfif arguments.expression EQ false&amp;gt;
		&amp;lt;cfthrow type=&quot;IllegalArgumentException&quot; message=msg &amp;amp; ToString(v)&amp;gt;
    &amp;lt;/cfif&amp;gt;
&amp;lt;/cffunction&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Key moments here are  &lt;i&gt;required=&quot;true|false&quot;&lt;/i&gt; in argument definitions and the IsDefined(&apos;arguments....&apos;) function which, well, defines whether optional arguments exist. Oh, and don&apos;t forget about type=&quot;any&quot; which allows you to pass arguments of any type. And the ToString function :)&lt;br /&gt;&lt;br /&gt;Function overloading - is, undoubtedly, great. But I&apos;ll trade it IsDefined most of the time (when it&apos;s uses are justified, of course :) )&lt;br /&gt;&lt;br /&gt;PS. Correct me if I&apos;m wrong, but does Java really not have access to the array of arguments passed to a function? And I&apos;m not talking about &lt;a href=&quot;http://java.sun.com/developer/JDCTechTips/2005/tt1018.html&quot;&gt;Variable arity&lt;/a&gt;.</description>
  <comments>http://community.livejournal.com/en_dmitriid/2884.html</comments>
  <category>java</category>
  <category>coldfusion</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/2602.html</guid>
  <pubDate>Thu, 17 Aug 2006 07:46:03 GMT</pubDate>
  <title>Coldfusion и XML</title>
  <link>http://community.livejournal.com/en_dmitriid/2602.html</link>
  <description>It is a major pain in the nether regions of the body to work with a language which provides reasonable tools for working with XML and provides no sane tools to modify XML. I&apos;m talking about ColdFusion.&lt;br /&gt;&lt;br /&gt;Suppose we have the following piece of XML:&lt;br /&gt;&lt;pre style=&quot;background-color: #efefef&quot;&gt;
&amp;lt;xml&amp;gt;
    &amp;lt;root&amp;gt;
        &amp;lt;elem&amp;gt;
            &amp;lt;value&amp;gt;Text&amp;lt;/value&amp;gt;
        &amp;lt;/elem&amp;gt;
    &amp;lt;/root&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If we read this piece into a variable called xmlDoc, we have &lt;i&gt;immedate&lt;/i&gt; access to the value &quot;Text&quot;:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background-color: #efefef&quot;&gt;
txt = xmlDoc.root.elem.value.xmlText;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now txt contains, as you may have guessed it, a string, &quot;Text&quot;.&lt;br /&gt;&lt;br /&gt;Moreover, if we have quite a handful of such elements, we may use an extremely convenient function XMLSearch which accepts (an unspecified subset of) XPath and returns an array of found elements.&lt;br /&gt;&lt;br /&gt;A real-world example now. Here&apos;s a stripped-down localization file from the project I&apos;m working on::&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background-color: #efefef&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;strings&amp;gt;
	&amp;lt;nspace NAME=&quot;global&quot;&amp;gt;
		&amp;lt;string CRC=&quot;73FB418E8CCD929E219338A555AA7EA4&quot;&amp;gt;
			&amp;lt;original&amp;gt;You need to login first&amp;lt;/original&amp;gt;
			&amp;lt;localized/&amp;gt;
		&amp;lt;/string&amp;gt;
		&amp;lt;string CRC=&quot;99DEA78007133396A7B8ED70578AC6AE&quot;&amp;gt;
			&amp;lt;original&amp;gt;Login&amp;lt;/original&amp;gt;
			&amp;lt;localized/&amp;gt;
		&amp;lt;/string&amp;gt;
	&amp;lt;/nspace&amp;gt;
	&amp;lt;controller NAME=&quot;admin&quot;&amp;gt;
		&amp;lt;action NAME=&quot;cities&quot;&amp;gt;
			&amp;lt;string CRC=&quot;FD8459135F9464065B708800B0BDF6D8&quot;&amp;gt;
				&amp;lt;original&amp;gt;Add a new city&amp;lt;/original&amp;gt;
				&amp;lt;localized/&amp;gt;
			&amp;lt;/string&amp;gt;
			&amp;lt;string CRC=&quot;F67FDD86A499050E0585BCA9EA023188&quot;&amp;gt;
				&amp;lt;original&amp;gt;Add city&amp;lt;/original&amp;gt;
				&amp;lt;localized/&amp;gt;
			&amp;lt;/string&amp;gt;
			&amp;lt;string CRC=&quot;4505DE1F3D02176AA6F1403778C5ADD1&quot;&amp;gt;
				&amp;lt;original&amp;gt;Region:&amp;lt;/original&amp;gt;
				&amp;lt;localized/&amp;gt;
			&amp;lt;/string&amp;gt;
		&amp;lt;/action&amp;gt;
	&amp;lt;/controller&amp;gt;
&amp;lt;/strings&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Searching across this monster of a file is trivial:&lt;br /&gt;&lt;pre style=&quot;background-color: #efefef&quot;&gt;
searchString = &quot;/strings/controller[@NAME=&quot;&quot;admin&quot;&quot;]/action[@NAME=&quot;&quot;cities&quot;&quot;]/string[@CRC=&quot;&quot;&lt;i&gt;CRC&lt;/i&gt;&quot;&quot;]&quot;;
elems = XmlSearch(xmlDoc, searchString);

/* If there&apos;s only one elems, we return it (simplified example): */

return elems[1].localized.xmlString;
&lt;/pre&gt;where CRC is calculated using obscure Vodoo rituals :)&lt;br /&gt;&lt;br /&gt;Now, the question is: what if we want to change the value oа this element? The procedure required to do that evokes an unbearable desire to nuke Macromedia offices :)&lt;br /&gt;&lt;br /&gt;Scanning thorugh the docs reveals that &lt;i&gt;the only standard procedure&lt;/i&gt; to change the desired value of a tag involves the use of ArrayAppend function on the array of &quot;value&quot; from the array of &quot;elem&quot; from the array of &quot;root&quot;...&lt;br /&gt;&lt;br /&gt;That is... You can find an element, but you cannot manipulate it directly. You have to take the root element. Then you have to take an array of first-level elements anв find the desired one. In that element you once again take an array (of second-level elements) and find the desired one. In that element you take an array of third-level elements and find the desired one. And finally, you take an array of fourth-level elements and find the desired one. If such an element does not exist, you append it to the array of fourth-level elements. Save.&lt;br /&gt;&lt;br /&gt;Anyway, here&apos;s what it looks like in the end:&lt;br /&gt;&lt;pre style=&quot;background-color: #efefef&quot;&gt;
// Add a new string
ArrayAppend(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].XmlChildren, XMLElemNew(xmlDoc, &quot;string&quot;));

// Find its position
stringIndex = ArrayLen(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].XmlChildren);

// Change its attribute
xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlAttributes.crc = Hash(t);

// Add &quot;original&quot; to it
ArrayAppend(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren, XMLElemNew(xmlDoc, &quot;original&quot;));

// Find original&apos;s position
orgIndex = ArrayLen(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren);

// Add text
xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].original.xmlText = t;

// Add &quot;localized&quot;
ArrayAppend(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren, XMLElemNew(xmlDoc, &quot;localized&quot;));

// Obtain its index
locIndex = ArrayLen(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren);

// Add text
xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].localized.xmlText = &apos;&apos;;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;:)))&lt;br /&gt;&lt;br /&gt;I am only grateful that I had to write this function only once. And it took me the better part of the day...</description>
  <comments>http://community.livejournal.com/en_dmitriid/2602.html</comments>
  <category>coldfusion</category>
  <category>xml</category>
  <category>wtf</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/2345.html</guid>
  <pubDate>Fri, 28 Jul 2006 07:53:00 GMT</pubDate>
  <title>Named Parameters</title>
  <link>http://community.livejournal.com/en_dmitriid/2345.html</link>
  <description>Ever since I saw Lisp I&apos;ve sorely missed named function parameters. What the heck is that? Ok, here goes...&lt;br /&gt;&lt;br /&gt;&lt;font size=&quot;1&quot;&gt;Lisp examples are quoted directly from &lt;/font&gt;&lt;a href=&quot;http://www.gigamonkeys.com/book/functions.html&quot;&gt;&lt;font size=&quot;1&quot;&gt;Practical Common Lisp&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let&apos;s refresh our knowledge of WinAPI - the dearly beloved API of all Windows developers. For instance, &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shellexecute.asp&quot;&gt;ShellExecute&lt;/a&gt;:&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;font color=&quot;#0000ff&quot;&gt;HINSTANCE&lt;/font&gt; ShellExecute(      
    &lt;font color=&quot;#0000ff&quot;&gt;HWND&lt;/font&gt; hwnd,
    &lt;font color=&quot;#0000ff&quot;&gt;LPCTSTR&lt;/font&gt; lpOperation,
    &lt;font color=&quot;#0000ff&quot;&gt;LPCTSTR&lt;/font&gt; lpFile,
    &lt;font color=&quot;#0000ff&quot;&gt;LPCTSTR&lt;/font&gt; lpParameters,
    &lt;font color=&quot;#0000ff&quot;&gt;LPCTSTR&lt;/font&gt; lpDirectory,
    &lt;font color=&quot;#0000ff&quot;&gt;INT&lt;/font&gt; nShowCmd
);
&lt;/pre&gt;On the whole I think I remember which parameters this function requires and why. Not too clearly though. I do remember the first three. The fourth might spring to mind while writing the function. The last too however, are quire elusive and I&apos;m never quite sure which goes where and when. The problem gets worse if you remember that som parameters, &lt;font face=&quot;Courier&quot;&gt;hwnd, lpParameters, lpDirectory&lt;/font&gt; in our case, are optional and can be replaced with NULLs. So, we would quite often invoke this function like this::&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;font color=&quot;#0000ff&quot;&gt; &lt;font color=&quot;#000000&quot;&gt;hResult =&lt;/font&gt; &lt;/font&gt;ShellExecute(NULL, &quot;open&quot;, &quot;path/to/file&quot;, NULL, NULL, SW_SHOWDEFAULT);
&lt;/pre&gt;Scary, huh? Now imagine if we could write this function like this:&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;font color=&quot;#0000ff&quot;&gt; &lt;font color=&quot;#000000&quot;&gt;hResult =&lt;/font&gt; &lt;/font&gt;ShellExecute(operation=&quot;open&quot;, file=&quot;path/to/file&quot;);
&lt;/pre&gt;Beautiful. Now, this is what named parameters are all about.&lt;br /&gt;&lt;br /&gt;Let&apos;s go back to Lisp. Let&apos;s consider the following function:&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;font color=&quot;#0000ff&quot;&gt; &lt;/font&gt;&lt;font color=&quot;#ff8000&quot;&gt;(&lt;/font&gt;&lt;strong&gt;defun&lt;/strong&gt; foo &lt;font color=&quot;#ff8000&quot;&gt;(&lt;/font&gt;&lt;strong&gt;&amp;amp;key&lt;/strong&gt; a b c&lt;font color=&quot;#ff8000&quot;&gt;) (&lt;/font&gt;&lt;strong&gt;list&lt;/strong&gt; a b c&lt;font color=&quot;#ff8000&quot;&gt;))&lt;/font&gt;
&lt;/pre&gt;&lt;br /&gt;This function accepts three parameters and simply listst them in their order. This is how this function behaves when we invoke it in numerous ways:&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
(foo)                ==&amp;gt; (NIL NIL NIL)
(foo :a 1)           ==&amp;gt; (1 NIL NIL)
(foo :b 1)           ==&amp;gt; (NIL 1 NIL)
(foo :c 1)           ==&amp;gt; (NIL NIL 1)
(foo :a 1 :c 3)      ==&amp;gt; (1 NIL 3)
(foo :a 1 :b 2 :c 3) ==&amp;gt; (1 2 3)
(foo :a 1 :c 3 :b 2) ==&amp;gt; (1 2 3)
&lt;/pre&gt;&lt;br /&gt;Note the last line. Even though the order or parameters is incorrect, the function still behaves as designed. Now, that&apos;s the beauty and power of named parameters. A developer now only needs to know &lt;strong&gt;which parameters&lt;/strong&gt; a function requires, not their &lt;strong&gt;not their order&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Unfortunately none of the mainstream languages support named parameters, not natively at least. That is why invoking a function (especially a WinApi function) is a long and tedious process whereas we could simply make do with passing a limited number of named arguments (as my example with ShellExecute shows).&lt;br /&gt;&lt;br /&gt;I am currently developing in ColdFusion and it supports named parameters natively (though you cannot honestly call it a mainstream language):&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;font color=&quot;#800000&quot;&gt;&amp;lt;&lt;strong&gt;cffunction&lt;/strong&gt;&lt;/font&gt; &lt;font color=&quot;#800000&quot;&gt;name=&lt;/font&gt;&quot;function&quot; &lt;font color=&quot;#800000&quot;&gt;access=&lt;/font&gt;&quot;public&quot;&lt;font color=&quot;#800000&quot;&gt;&amp;gt;&lt;/font&gt;
    &lt;font color=&quot;#800000&quot;&gt;&amp;lt;&lt;strong&gt;cfargument&lt;/strong&gt; name=&lt;/font&gt;&quot;arg1&quot; &lt;font color=&quot;#800000&quot;&gt;type=&lt;/font&gt;&quot;numeric&quot; &lt;font color=&quot;#800000&quot;&gt;required=&lt;/font&gt;&quot;yes&quot;&amp;gt;
&lt;font color=&quot;#800000&quot;&gt;    &amp;lt;&lt;strong&gt;cfargument&lt;/strong&gt; name=&lt;/font&gt;&quot;arg2&quot; &lt;font color=&quot;#800000&quot;&gt;type=&lt;/font&gt;&quot;string&quot; &lt;font color=&quot;#800000&quot;&gt;required=&lt;/font&gt;&quot;no&quot;&amp;gt;
    &lt;font color=&quot;#ff8000&quot;&gt;&amp;lt;!--- и так далее ---&amp;gt;&lt;/font&gt;


&lt;font color=&quot;#800000&quot;&gt;&amp;lt;/&lt;strong&gt;cffunction&lt;/strong&gt;&amp;gt;&lt;/font&gt;
&lt;/pre&gt;This function is invoked as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;font color=&quot;#800000&quot;&gt;&amp;lt;&lt;strong&gt;cfset&lt;/strong&gt;&lt;/font&gt; &lt;font color=&quot;#800000&quot;&gt;function(arg1=1, arg2=&apos;string&apos;)&lt;/font&gt;&lt;font color=&quot;#800000&quot;&gt;&amp;gt;&lt;/font&gt;
&lt;/pre&gt;As in Lisp, the order of arguments is not important as long as they are named.&lt;br /&gt;&lt;br /&gt;Some languages (scripting languages, mostly) emulate this behaviour through the use of hashes. PHP anyone?&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;strong&gt;function&lt;/strong&gt; a_func($params)
{
    &lt;strong&gt;if&lt;/strong&gt;(&lt;font color=&quot;#000080&quot;&gt;isset&lt;/font&gt;($params[&lt;font color=&quot;#800000&quot;&gt;&apos;arg1&apos;&lt;/font&gt;])) &lt;font color=&quot;#008000&quot;&gt;/* do stuff */&lt;/font&gt;
    &lt;strong&gt;if&lt;/strong&gt;(&lt;font color=&quot;#000080&quot;&gt;isset&lt;/font&gt;($params[&lt;font color=&quot;#800000&quot;&gt;&apos;arg2&apos;&lt;/font&gt;])) &lt;font color=&quot;#008000&quot;&gt;/* do stuff */&lt;/font&gt;
}
&amp;nbsp;
&lt;font color=&quot;#008000&quot;&gt;/* Calling the function */&lt;/font&gt;
$result = a_func(&lt;font color=&quot;#000080&quot;&gt;array&lt;/font&gt;(&lt;font color=&quot;#800000&quot;&gt;&apos;arg1&apos;&lt;/font&gt; =&amp;gt; &lt;font color=&quot;#0000ff&quot;&gt;123&lt;/font&gt;, &lt;font color=&quot;#800000&quot;&gt;&apos;arg2&apos;&lt;/font&gt; =&amp;gt; &lt;font color=&quot;#800000&quot;&gt;&apos;a string&apos;&lt;/font&gt;));
&lt;/pre&gt;That is, we actually pass an array, but it serves our purpose well enough. Ruby employs exactly the same technique:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;BACKGROUND-COLOR: #efefef&quot;&gt;
&lt;font color=&quot;#008000&quot;&gt;# find from ActiveRecord
&lt;/font&gt;      &lt;font color=&quot;#000080&quot;&gt;&lt;strong&gt;def&lt;/strong&gt;&lt;/font&gt; &lt;font color=&quot;#008080&quot;&gt;&lt;strong&gt;find&lt;/strong&gt;&lt;/font&gt;(*args)
        options = extract_options_from_args!(args)
        validate_find_options(options)
        set_readonly_option!(options)

        &lt;font color=&quot;#000080&quot;&gt;&lt;strong&gt;case&lt;/strong&gt;&lt;/font&gt; args.first
          &lt;font color=&quot;#000080&quot;&gt;&lt;strong&gt;when&lt;/strong&gt;&lt;/font&gt; &lt;font color=&quot;#808000&quot;&gt;:first&lt;/font&gt; &lt;strong&gt;&lt;font color=&quot;#000080&quot;&gt;then&lt;/font&gt;&lt;/strong&gt; find_initial(options)
          &lt;font color=&quot;#000080&quot;&gt;&lt;strong&gt;when&lt;/strong&gt;&lt;/font&gt; &lt;font color=&quot;#808000&quot;&gt;:all&lt;/font&gt;   &lt;strong&gt;&lt;font color=&quot;#000080&quot;&gt;then&lt;/font&gt;&lt;/strong&gt; find_every(options)
          &lt;font color=&quot;#000080&quot;&gt;&lt;strong&gt;else&lt;/strong&gt;&lt;/font&gt;             find_from_ids(args, options)
        &lt;font color=&quot;#000080&quot;&gt;&lt;strong&gt;end
      end
&lt;/strong&gt;&lt;font color=&quot;#008000&quot;&gt;
&amp;nbsp;
# Calling the function:&lt;/font&gt;
&lt;font color=&quot;#000000&quot;&gt;Person.&lt;font color=&quot;#000000&quot;&gt;find&lt;/font&gt;(&lt;font color=&quot;#808000&quot;&gt;:first&lt;/font&gt;, &lt;font color=&quot;#808000&quot;&gt;:order&lt;/font&gt; =&amp;gt; &lt;font color=&quot;#800080&quot;&gt;&quot;created_on DESC&quot;&lt;/font&gt;, &lt;font color=&quot;#808000&quot;&gt;:offset&lt;/font&gt; =&amp;gt; &lt;font color=&quot;#008080&quot;&gt;5&lt;/font&gt;)
Person.&lt;font color=&quot;#000000&quot;&gt;find&lt;/font&gt;(&lt;font color=&quot;#808000&quot;&gt;:all&lt;/font&gt;, &lt;font color=&quot;#808000&quot;&gt;:group&lt;/font&gt; =&amp;gt; &lt;font color=&quot;#800080&quot;&gt;&quot;category&quot;&lt;/font&gt;)
Person.&lt;font color=&quot;#000000&quot;&gt;find&lt;/font&gt;(&lt;font color=&quot;#808000&quot;&gt;:all&lt;/font&gt;, &lt;font color=&quot;#808000&quot;&gt;:offset&lt;/font&gt; =&amp;gt; &lt;font color=&quot;#008080&quot;&gt;10&lt;/font&gt;, &lt;font color=&quot;#808000&quot;&gt;:limit&lt;/font&gt; =&amp;gt; &lt;font color=&quot;#008080&quot;&gt;10&lt;/font&gt;)&lt;/font&gt;
&lt;font color=&quot;#008000&quot;&gt;# where Person is an object of type Activerecord&lt;/font&gt;
&lt;/font&gt;&lt;/pre&gt;However, none of these can even compare to Lisp&apos;s implementation. ColdFusion, for instance, doesn&apos;t accept an arbitrary number of parameters (see Lisp&apos;s &amp;rest). Hashes both in PHP and Ruby are rather cumbersome because implementation of the function may become convoluted (or you have to resort to using less-than-safe &lt;a href=&quot;http://tr.php.net/manual/en/function.extract.php&quot;&gt;extract&lt;/a&gt; or &lt;a href=&quot;http://caboo.se/doc/classes/ActiveRecord/Base.html#M005745&quot;&gt;extract_options_from_args!&lt;/a&gt; functions). I&apos;m not even talking other languages like С/С++, C# and Java :). Some languages though, like Haskell, Erlang and Nemerle, have pattern matching allows the developer to work arounв named parameters in a very elegant manner, but that is a story for another day.</description>
  <comments>http://community.livejournal.com/en_dmitriid/2345.html</comments>
  <category>ruby</category>
  <category>coldfusion</category>
  <category>lisp</category>
  <category>php</category>
  <category>general</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/2208.html</guid>
  <pubDate>Wed, 26 Jul 2006 07:29:20 GMT</pubDate>
  <title>Running along the rails</title>
  <link>http://community.livejournal.com/en_dmitriid/2208.html</link>
  <description>In July 2006 CNN Money gave a fellow named David Heinemeier Hansson the 50th place in their &lt;a href=&quot;http://money.cnn.com/magazines/business2/peoplewhomatter/index.html&quot;&gt;list of most influential people in contemporary online business&lt;/a&gt; (also known as Business 2.0).&lt;br /&gt;&lt;br /&gt;What? You don&apos;t know who this fellow is? Well, he is the creator of &lt;a href=&quot;http://www.rubyonrails.org/&quot;&gt;Ruby on Rails&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ruby on Rails is an iPod of online technologies:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;    Like iPod, Rails doesn&apos;t use any new revolutionary technologies:&lt;br /&gt;    &lt;ul&gt;&lt;br /&gt;        &lt;li&gt; - Ruby itself appeared in 1995 &lt;/li&gt;&lt;br /&gt;        &lt;li&gt; - The MVC (Model-View-Controller) pattern was first described back in 1979 &lt;/li&gt;&lt;br /&gt;    &lt;/ul&gt;&lt;br /&gt;    and so on&lt;br /&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;    Both iPod and Rails, when they appeared, were the cause an unprecedented buzz and discussion.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;    Rails&apos;s fans, much like iPod&apos;s fans, are blind to the shortcomings of their favorite toy and are ready to rip any critic to pieces (or worse).&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;    Rails, like iPod, has created numerous clones which are striving to duplicate the functionality without actually introducing any new ideas:&lt;br /&gt;    &lt;ul&gt;&lt;br /&gt;        &lt;li&gt; - PHP:  &lt;a href=&quot;http://cakephp.org/&quot;&gt;CakePHP&lt;/a&gt; and &lt;a href=&quot;http://framework.zend.com/&quot;&gt;Zend Framework&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;        &lt;li&gt; - ColdFusion: &lt;a href=&quot;http://cfwheels.com/&quot;&gt;ColdFusion on Wheels&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;        &lt;li&gt; - .NET: &lt;a href=&quot;http://www.castleproject.org/index.php/MonoRail&quot;&gt;MonoRail&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;        &lt;li&gt; - Perl has &lt;a href=&quot;http://www.catalystframework.org/&quot;&gt;Catalyst&lt;/a&gt;, though this framewrok isn&apos;t originally based on Rails&lt;/li&gt;&lt;br /&gt;        &lt;li&gt; - Python has &lt;a href=&quot;http://www.turbogears.org/&quot;&gt;TurboGears&lt;/a&gt;, though its creator stated that this is not a Rails clone&lt;/li&gt;&lt;br /&gt;    &lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;So, why Rails has not only appeared, but also become very popular and eagerly cloned?&lt;br /&gt;&lt;br /&gt;I suppose this happened because Rails (and iPod, too) showed us that technology can be humane. &lt;br /&gt;&lt;br /&gt;In the case of Rails you can obtain interesting result fast - lightning fast (nonbelievers can check out &lt;a href=&quot;http://www.rubyonrails.org/screencasts&quot;&gt;Rails screencasts&lt;/a&gt;). Most of the time you spend in Rails is not fighting databases, or sessions, or files, or anything else, but actually writing the logic of your application.&lt;br /&gt;&lt;br /&gt;Additionally, Rails lowers the entry level for the MVC pattern (quite a complex pattern, actually). You simply forget about it, it comes to you naturally.&lt;br /&gt;&lt;br /&gt;Rails is, in essence, a ready and sound foundation that let&apos;s you build your own house. You may choose either a number of available blocks or just build everything brick by brick. Most other framewroks, on the contrary, have been providing you with either a finished house or with a number of raw materials and a dozer.&lt;br /&gt;&lt;br /&gt;So, this David Heinemeier Hansson fella has again proved that no &quot;designed by committee&quot; system/framework (even if this committee is a multi-billion dollar corporation) can ever compete with frameworks that people build for themselves. After all, people know better about their own needs than a committe ever will.&lt;br /&gt;&lt;br /&gt;Anyway, I can&apos;t wait to see what happens to web technologies 5 years from now. After all, too many developers have accustomed themselves to thу idea of humane technology to ever turn back. I hope.</description>
  <comments>http://community.livejournal.com/en_dmitriid/2208.html</comments>
  <category>web</category>
  <category>rails</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/1808.html</guid>
  <pubDate>Thu, 20 Jul 2006 09:44:14 GMT</pubDate>
  <title>Winter has come...</title>
  <link>http://community.livejournal.com/en_dmitriid/1808.html</link>
  <description>After some consideration we have decided to develop our project in ColdFusion. The reason is simple - there are some developers who can help us should the need arise. There are no Rubyists in sight, however...&lt;br /&gt;&lt;br /&gt;I have mixed feelings about ColdFusion so far. I&apos;m quite unnerved by CFML (sort of SGML-based, but not quite) and DreamWeaver&apos;s stupid-stupid-stupid wizards which break all code formatting once applied.&lt;br /&gt;&lt;br /&gt;Stay tuned for more rants...</description>
  <comments>http://community.livejournal.com/en_dmitriid/1808.html</comments>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/1622.html</guid>
  <pubDate>Tue, 04 Jul 2006 16:13:13 GMT</pubDate>
  <title>Web programming. Revisited</title>
  <link>http://community.livejournal.com/en_dmitriid/1622.html</link>
  <description>On the heels of &lt;a href=&quot;http://community.livejournal.com/ru_dmitriid/1464.html&quot;&gt;the last post&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;Found &lt;a href=&quot;http://community.livejournal.com/en_dmitriid/1386.html&quot;&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://hinchcliffe.org/img/web20stratigraphic.jpg&quot; title=&quot;&quot;&gt;&lt;br /&gt;&lt;br /&gt;Where else, other than in Web programming that is, can you find such a mash-up? :)</description>
  <comments>http://community.livejournal.com/en_dmitriid/1622.html</comments>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/1386.html</guid>
  <pubDate>Mon, 03 Jul 2006 10:01:30 GMT</pubDate>
  <title>A web programmer&apos;s lament</title>
  <link>http://community.livejournal.com/en_dmitriid/1386.html</link>
  <description>Web programmers are generally viewed as &quot;less-than-programmers&quot;. Some even think that they are not programmers at all, come to think of it. Indeed, some &lt;i&gt;think&lt;/i&gt; that creating something like &lt;a href=&quot;http://codeproject.com&quot;&gt;Codeproject&lt;/a&gt; is a piece of cake. Those same people also think that creating a yet another accounting program in Visual Basic (or, god forbid, VBA) is uber-cool and is worthy of all praise.&lt;br /&gt;&lt;br /&gt;Now, why would anybody think that? Huh?&lt;br /&gt;&lt;br /&gt;Let&apos;s consider the so-called &quot;application programmer&quot;. Or even the so-called &quot;systems programmer&quot;. All they ever need to know is their favorite programming language (C/C++/Java/Object Pascal...). Well, quite often something like a passing knowledge of SQL comes along and a declarative language to store application settings in (usually the INI file format or XML). &lt;i&gt;In toto&lt;/i&gt; - at most three technologies: programming language, SQL, XML, and chances are the programmer will use datasets and MSXML to work with the latter to.&lt;br /&gt;&lt;br /&gt;What about the web programmer, then?&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Favorite programming language - one of PHP/Ruby/Perl/Java/C#/Python &lt;/li&gt;&lt;br /&gt;&lt;li&gt; SQL &lt;/li&gt;&lt;br /&gt;&lt;li&gt; HTML &lt;/li&gt;&lt;br /&gt;&lt;li&gt; CSS &lt;/li&gt;&lt;br /&gt;&lt;li&gt; JavaScript (sometimes with an added bonus of JSON) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; and quite often XML &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Also throw in the bag the fact that web programming is &lt;i&gt;originally and immediately&lt;/i&gt; a client-server programming. Most of application programmers don&apos;t even have a clue about what&apos;s that all about.&lt;br /&gt;&lt;br /&gt;So, what we have in the end is that the despised web programmers actually know and do the following:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; They program client-server applications easily and effortlessly&lt;/li&gt;&lt;br /&gt;&lt;li&gt; They combine imperative and declarative programming seamlessly &lt;/li&gt;&lt;br /&gt;&lt;li&gt; They have a more-than-passing knowledge about about non-compatible and non-intersecting technologies and know how to combine them &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;And as soon as the project starts to grow... We have data replication, distributed servers and son on and so forth...&lt;br /&gt;&lt;br /&gt;And still web programming is perceived to be a child&apos;s play whereas grown-ups are off working on their &quot;serious&quot; technologies which are supposedly to hard for a web-programmer to comprehend. Well, think again, lads. It is we, web porgrammers, who look down on you because most of the technologies most of you are just beginning to toy with have already been seen, learned and taken to use by us.&lt;br /&gt;&lt;br /&gt;BTW, this discrimination against web programming is exactly the reason why web programmers are so behind on tools and libraries. It is only recently that decent tools have sprung up all over the place (such as &lt;a href=&quot;http://www.rubyonrails.org/&quot;&gt;Ruby on Rails&lt;/a&gt;, &lt;a href=&quot;http://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt;, &lt;a href=&quot;http://www.jboss.com/products/seam&quot;&gt;Seam&lt;/a&gt;, &lt;a href=&quot;http://www.xisc.com/&quot;&gt;Prado&lt;/a&gt; and others)&lt;br /&gt;&lt;br /&gt;Now that&apos;s a bloody shame if you ask me.</description>
  <comments>http://community.livejournal.com/en_dmitriid/1386.html</comments>
  <category>web</category>
  <category>sql</category>
  <category>html</category>
  <category>php</category>
  <category>javascript</category>
  <category>ruby</category>
  <category>css</category>
  <category>wtf</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/1071.html</guid>
  <pubDate>Fri, 23 Jun 2006 15:19:10 GMT</pubDate>
  <title>WTF</title>
  <link>http://community.livejournal.com/en_dmitriid/1071.html</link>
  <description>As I promised, this entry will contain code I submitted to &lt;a href=&quot;http://thedailywtf.com/&quot;&gt;The Daily WTF&lt;/a&gt;. Of course, my code cannot even compete with the true gems of TheDailyWTF, but here goes...&lt;br /&gt;&lt;br /&gt;We&apos;re using &lt;a href=&quot;http://www.symantec.com/home_homeoffice/ products/overview.jsp?pcid=pf&amp;amp;pvid=wfp10&quot;&gt;Symantec WinFax Pro&lt;/a&gt;. Among other things it provides a set of COM objects that allow a programmer to manipulate incoming/outgoing faxes, read their status, send faxes etc. One of the main objects is the CSDKLog object. It provides to quite important (no pun or irony intended) functions:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background-color: #EFEFEF&quot;&gt;
  BSTR GetMessageDate(BSTR MessageID)
  BSTR GetMessageTime(BSTR MessageID)
&amp;#160;
&lt;/pre&gt;&lt;br /&gt;Note that these two functions return a BSTR (for those of you who are lucky not to know this it means Yet Another C++ String Class, Com-style). Ok, it&apos;s fine by me as long as this string contains some sort of standard code. Let&apos;s say &quot;20062306&quot; and &quot;231451&quot; for &quot;11:14:51 PM, June 23rd, 2006&quot;. Yeah right. Both return a locale-formatted string. WTF you ask? Here&apos;s TF:&lt;br /&gt;&lt;br /&gt;Let&apos;s take the aforementioned &quot;11:14:51 PM, June 23rd, 2006&quot;. GetMessageDate and GetMessageTime return:&lt;br /&gt;&lt;pre style=&quot;background-color: #EFEFEF&quot;&gt;
  US locale:    06/23/2006    11:14:51 РМ
  RU locale:    23.06.2006    23:14:51
&amp;#160;
&lt;/pre&gt;and so on&lt;br /&gt;&lt;br /&gt;At least three computers in our office have US Locale. The rest use identical (as far as date/time display is concerned) Ru and TR locales. What will a programmer do? He will do the following::&lt;br /&gt;&lt;pre style=&quot;background-color: #EFEFEF&quot;&gt;
           static bool isUSDate(char* date)
	{
		std::string df(date);

		int i = df.find(&apos;/&apos;);

		return i &amp;gt; 0;
	}

	static int dayFromUSDate(char* date)
	{
		std::string df(date);

		df = df.substr(df.find(&apos;/&apos;) + 1);
		df = df.substr(0, df.find(&apos;/&apos;));

		return atoi(df.c_str());
	}

	static int monthFromUSDate(char* date)
	{
		std::string df(date);

		df = df.substr(0, df.find(&apos;/&apos;));

		return atoi(df.c_str());
	}

	static int yearFromUSDate(char* date)
	{
		std::string df(date);

		df = df.substr(df.find(&apos;/&apos;) + 1);
		df = df.substr(df.find(&apos;/&apos;) + 1);

		return atoi(df.c_str());
	}

	static int dayFromEuDate(char* date)
	{
		std::string df(date);

		df = df.substr(0, df.find(&apos;.&apos;));

		return atoi(df.c_str());
	}
	static int monthFromEuDate(char* date)
	{
		std::string df(date);

		df = df.substr(df.find(&apos;.&apos;) + 1);
		df = df.substr(0, df.find(&apos;.&apos;));

		return atoi(df.c_str());
	}
	static int yearFromEuDate(char* date)
	{
		std::string df(date);

		df = df.substr(df.find(&apos;.&apos;) + 1);
		df = df.substr(df.find(&apos;.&apos;) + 1);

		return atoi(df.c_str());
	}

	static int hourFromTime(char* date)
	{
		std::string df(date);

		df = df.substr(0, df.find(&apos;:&apos;));

		return atoi(df.c_str());
	}

	static int minuteFromTime(char* date)
	{
		std::string df(date);

		df = df.substr(df.find(&apos;:&apos;) + 1);
		df = df.substr(0, df.find(&apos;:&apos;));

		return atoi(df.c_str());
	}
	static int secondFromTime(char* date)
	{
		std::string df(date);

		df = df.substr(df.find(&apos;:&apos;) + 1);
		df = df.substr(df.find(&apos;:&apos;) + 1);

		df = df.substr(0, df.find(&apos; &apos;)); /* Brit/US AM/PM */
		df = df.substr(0, df.find(&apos;P&apos;));
		df = df.substr(0, df.find(&apos;A&apos;));

		return atoi(df.c_str());
	}
&amp;#160;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;:))))))))))) What else could I do? I had deadlines, man....&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://utx.ambience.ru/users/dmitriid/C++&quot; rel=&quot;tag&quot;&gt;&lt;img src=&quot;http://utx.ambience.ru/img/dmitriid/C++&quot; style=&quot;border: 0px solid; background-color: #cc0000; width: 30px; height: 5px; margin: 3px;&quot; alt=&quot;C++&quot; title=&quot;C++&quot;&gt;&lt;/a&gt; &lt;a href=&quot;http://utx.ambience.ru/users/dmitriid/COM&quot; rel=&quot;tag&quot;&gt;&lt;img src=&quot;http://utx.ambience.ru/img/dmitriid/COM&quot; style=&quot;border: 0px solid; background-color: #cc0000; width: 30px; height: 5px; margin: 3px;&quot; alt=&quot;COM&quot; title=&quot;COM&quot;&gt;&lt;/a&gt; &lt;a href=&quot;http://utx.ambience.ru/users/dmitriid/WTF&quot; rel=&quot;tag&quot;&gt;&lt;img src=&quot;http://utx.ambience.ru/img/dmitriid/WTF&quot; style=&quot;border: 0px solid; background-color: #cc0000; width: 30px; height: 5px; margin: 3px;&quot; alt=&quot;WTF&quot; title=&quot;WTF&quot;&gt;&lt;/a&gt;</description>
  <comments>http://community.livejournal.com/en_dmitriid/1071.html</comments>
  <category>com</category>
  <category>c++</category>
  <category>wtf</category>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/866.html</guid>
  <pubDate>Fri, 16 Jun 2006 16:34:02 GMT</pubDate>
  <title>The Daily WTF</title>
  <link>http://community.livejournal.com/en_dmitriid/866.html</link>
  <description>Shoot. Never thought I would live to see this day. I just submitted some of my own code (the code I&apos;ve just written today, not less) to &lt;a href=&quot;http://thedailywtf.com/&quot;&gt;The Daily WTF&lt;/a&gt;. If this code appears on the front page, it will be kinda cool. In a sick sort of way :)&lt;br /&gt;&lt;br /&gt;If it doesn&apos;t appear, I will repost it here</description>
  <comments>http://community.livejournal.com/en_dmitriid/866.html</comments>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
<item>
  <guid isPermaLink='true'>http://community.livejournal.com/en_dmitriid/694.html</guid>
  <pubDate>Mon, 12 Jun 2006 10:06:29 GMT</pubDate>
  <title>Microsoft finally catching up...</title>
  <link>http://community.livejournal.com/en_dmitriid/694.html</link>
  <description>Microsoft has finally released an embedded SQL Server. &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?familyid=85e0c3ce-3fa1-453a-8ce9-af6ca20946c3&amp;amp;displaylang=en&quot;&gt;Microsoft SQL Server 2005 Everywhere Edition CTP&lt;/a&gt; is now available for download. This could and will take a large portion of Windows-only developers away from Firebird and SQLite.</description>
  <comments>http://community.livejournal.com/en_dmitriid/694.html</comments>
  <lj:security>public</lj:security>
  <lj:poster>dmitriid</lj:poster>
</item>
</channel>
</rss>
